// run: $exec < input
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

struct pos
{
	int x, y;
};

int const maxn = 1010;
int const inf = 1 << 30;
char da[maxn][maxn];
bool vis[maxn][maxn];
int dis[maxn][maxn][5];
bool map[5][5];
int n, m;

int const opt[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

bool inrange(int x, int y)
{
	return (x >= 0 && x < n) && (y >= 0 && y < m);
}

bool is_state(char ch)
{
	return ch == '1' || ch == '2' || ch == '3';
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			std::cin >> da[i][j];
			for (int tt = 0; tt < 4; tt++) dis[i][j][tt] = inf;
		}

	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			if (is_state(da[i][j])) {
				for (int t = 0; t < 4; t++) {
					int px = i + opt[t][0];
					int py = j + opt[t][1];
					if (inrange(px, py) && is_state(da[px][py])) {
						int u = da[i][j] - '1';
						int v = da[px][py] - '1';
						map[u][v] = map[v][u] = true;
					}
				}
			}
		}

	for (int ti = 1; ti <= 3; ti++) {
		std::queue<pos> q;
		std::memset(vis, 0, sizeof(vis));
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (da[i][j] - '0' == ti) {
					q.push({i, j});
					vis[i][j] = true;
					dis[i][j][ti - 1] = 0;
				}
			}

		while (!q.empty()) {
			pos tmp = q.front(); q.pop();
			for (int i = 0; i < 4; i++) {
				int px = tmp.x + opt[i][0];
				int py = tmp.y + opt[i][1];
				if (inrange(px, py) && !vis[px][py]) {
					dis[px][py][ti - 1] = dis[tmp.x][tmp.y][ti - 1] + 1;
					vis[px][py] = true;
					q.push({px, py});
				}
			}
		}
	}

	int ans = inf;
	if (map[0][1] && map[1][2]) map[0][2] = true;
	if (map[0][2] && map[2][1]) map[0][1] = true;
	if (map[0][1] && map[0][2]) map[1][2] = true;

	if (map[0][1] && map[1][2]) ans = 0;
	else {
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++) {
				if (da[i][j] != '.') continue;
				if (map[0][1]) ans = std::min(ans, dis[i][j][2] + std::min(dis[i][j][0], dis[i][j][1]));
				else
				if (map[0][2]) ans = std::min(ans, dis[i][j][1] + std::min(dis[i][j][0], dis[i][j][2]));
				else
				if (map[1][2]) ans = std::min(ans, dis[i][j][1] + std::min(dis[i][j][0], dis[i][j][2]));
				else
					ans = std::min(ans, dis[i][j][0] + dis[i][j][1] + dis[i][j][2]);
			}
	}
	if (ans >= inf) ans = -1;
	std::cout << ans << '\n';
}

